package it.polito.let.http.parser;

import java_cup.runtime.*;
import java.io.IOException;
import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;

import static it.polito.let.http.parser.HTTPSym.*;

%%

%class HTTPLex

%unicode
%line
%column

%public
// %final
// %abstract

//%standalone
%cupsym HTTPSym
%cup
// %cupdebug


%init{
	// TODO: code that goes to constructor
%init}

%{
	private static final boolean DEBUG = false;
	
	private Symbol sym(int type)
	{
		return new Symbol(type, yyline, yycolumn); 
	}

	private Symbol sym(int type, Object value)
	{
		return new Symbol(type, yyline, yycolumn, value);
	}

	private void error()
	throws IOException
	{
		throw new IOException("illegal text at line = "+yyline+", column = "+yycolumn+", text = '"+yytext()+"'");
	}
	
	private void trace(String s) {
		if (DEBUG)
			System.out.println(s);
	}
	
	private String URLDecode (String s) {
		try {
			return URLDecoder.decode(s,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}
%}

ANY			=	.
ws			=	"+"|"%09"
INTEGER		=   ("%2B"|"-")?[1-9][0-9]*|0
FLOAT		=	("%2B"|"-")?(([0-9]+"."[0-9]*)|([0-9]*"."[0-9]+))(e|E("%2B"|"-")?[0-9]+)?
BOOL		=	true|false
URLENC		= 	[0-9A-Za-z_.%*+-]+

%%
"&"					{ trace("SEP"); return sym(HTTPSym.SEP); }
"="					{ trace("EQUALS"); return sym(HTTPSym.EQUALS); }
"formid"			{ trace("FORMID"); return sym(HTTPSym.FORMID); }
{ws}*{INTEGER}{ws}*	{ trace("INTEGER: "+yytext()+" => "+URLDecode(yytext()));
					  try { return sym(HTTPSym.INTEGER, Integer.parseInt(URLDecode(yytext()).trim())); } catch (Exception e) { error(); } }
{ws}*{FLOAT}{ws}*	{ trace("FLOAT: "+yytext()+" => "+URLDecode(yytext()));
					  try { return sym(HTTPSym.FLOAT, new Float(URLDecode(yytext()).trim())); } catch (Exception e) { error(); } }
{ws}*{BOOL}{ws}*	{ trace("BOOL: "+yytext()+" => "+URLDecode(yytext())); 
					  try { return sym(HTTPSym.BOOLEAN, new Boolean(URLDecode(yytext()).trim())); } catch (Exception e) { error(); } }
{URLENC}			{ trace("STRING: "+yytext()+" => "+URLDecode(yytext()));
					  try { return sym(HTTPSym.STRING,URLDecode(yytext())); } catch (Exception e) { error(); } }
{ANY}				{ error(); }
